#include "CH57x_common.h"
#include "string.h"
#include "eth_driver.h"
#include "mqtt.h"
#include "MQTTPacket.h"


MQTT_Config_t mqtt_config;

extern UINT8 SocketId;

//uint16_t desport = 1883;                           //MQTT server port
//uint16_t srcport = 4200;                           //source port

int pub_qos = 0;                                   //Publish quality of service
int sub_qos = 0;                                   //Subscription quality of service
char *username  = "gateway_mqtt";                         //Device name, unique for each device, available "/" for classification
char *password  = "gateway_mqtt";                         //Server login password
char *sub_topic = "topic/1";                       //subscribed session name
char *pub_topic = "topic/1";                       //Published session name
char *payload = "WCHNET MQTT";                     //Publish content

uint8_t con_flag  = 0;                             //Connect MQTT server flag
uint8_t pub_flag  = 0;                             //Publish session message flag/
uint8_t sub_flag  = 0;                             //Subscription session flag
uint8_t tout_flag = 0;                             //time-out flag
uint16_t packetid = 5;                             //package id
uint8_t publishValid = 0;
uint16_t timeCnt = 0;

extern void mStopIfError(UINT8 iError);


void mqtt_init()
{
	strcpy(mqtt_config.user_name,"gateway_mqtt");
	strcpy(mqtt_config.passwd,"gateway_mqtt");
	mqtt_config.port = 1883;
	
	mqtt_config.IP[0] = 112;
	mqtt_config.IP[1] = 74;
	mqtt_config.IP[2] = 97;
	mqtt_config.IP[3] = 118;
	
	strcpy((char *)&mqtt_config.Subscribed_topic[0][0],"topic/1");
	strcpy((char *)&mqtt_config.Subscribed_topic[1][0],"topic/2");
	strcpy((char *)&mqtt_config.Subscribed_topic[2][0],"topic/3");
	strcpy((char *)&mqtt_config.Subscribed_topic[3][0],"topic/4");

}
/*********************************************************************
 * @fn      Transport_Open
 *
 * @brief   open the TCP connection.
 *
 * @return  socket id
 */
uint8_t Transport_Open(void)
{
    uint8_t i;
    SOCK_INF TmpSocketInf;

    memset((void *)&TmpSocketInf,0,sizeof(SOCK_INF));
    memcpy((void *)TmpSocketInf.IPAddr,mqtt_config.IP,4);
    TmpSocketInf.DesPort = mqtt_config.port;
    TmpSocketInf.SourPort = 4200;
    TmpSocketInf.ProtoType = PROTO_TYPE_TCP;
    TmpSocketInf.RecvBufLen = RECE_BUF_LEN;
    i = WCHNET_SocketCreat(&SocketId,&TmpSocketInf);
    mStopIfError(i);

    i = WCHNET_SocketConnect(SocketId);
    mStopIfError(i);
    return SocketId;
}

/*********************************************************************
 * @fn      Transport_Close
 *
 * @brief   close the TCP connection.
 *
 * @return  @ERR_T
 */
uint8_t Transport_Close(void)
{
    uint8_t i;
    i = WCHNET_SocketClose(SocketId,TCP_CLOSE_NORMAL);
    mStopIfError(i);
    return i;
}

/*********************************************************************
 * @fn      Transport_SendPacket
 *
 * @brief   send data.
 *
 * @param   buf - data buff
 *          len - data length
 *
 * @return  none
 */
void Transport_SendPacket(uint8_t *buf, uint32_t len)
{
	WCHNET_SocketSend(SocketId, buf, &len);
	printf("%d bytes uploaded!\r\n",len);
}

/*********************************************************************
 * @fn      MQTT_Connect
 *
 * @brief   Establish MQTT connection.
 *
 * @param   username - user name.
 *          password - password
 *
 * @return  none
 */
void MQTT_Connect(char *username, char *password)
{
    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
    uint32_t len;
    uint8_t buf[200];

    data.clientID.cstring = "admin1";
    data.keepAliveInterval = 2000;
    data.cleansession = 1;
    data.username.cstring = username;
    data.password.cstring = password;

    len = MQTTSerialize_connect(buf,sizeof(buf),&data);
    Transport_SendPacket(buf,len);
}

/*********************************************************************
 * @fn      MQTT_Subscribe
 *
 * @brief   MQTT subscribes to a topic.
 *
 * @param   topic - Topic name to subscribe to
 *          req_qos - quality of service
 *
 * @return  none
 */
void MQTT_Subscribe( char *topic,int req_qos)
{
    MQTTString topicString = MQTTString_initializer;
    uint32_t len;
    uint32_t msgid = 1;
    uint8_t buf[200];

    topicString.cstring = topic;
    len = MQTTSerialize_subscribe(buf,sizeof(buf),0,msgid,1,&topicString,&req_qos);
    Transport_SendPacket(buf,len);
}

/*********************************************************************
 * @fn      MQTT_Unsubscribe
 *
 * @brief   MQTT unsubscribe from a topic.
 *
 * @param   topic - Topic name to unsubscribe to.
 *
 * @return  none
 */
void MQTT_Unsubscribe(char *topic)
{
    MQTTString topicString = MQTTString_initializer;
    uint32_t len;
    uint32_t msgid = 1;
    uint8_t buf[200];

    topicString.cstring = topic;
    len = MQTTSerialize_unsubscribe(buf,sizeof(buf),0,msgid,1,&topicString);
    Transport_SendPacket(buf,len);
}

/*********************************************************************
 * @fn      MQTT_Publish
 *
 * @brief   MQTT publishes a topic.
 *
 * @param   topic - Published topic name.
 *          qos - quality of service
 *          payload - data buff
 *
 * @return  none
 */
void MQTT_Publish(char *topic, int qos, char *payload)
{
    MQTTString topicString = MQTTString_initializer;
    uint32_t payloadlen;
    uint32_t len;
    uint8_t buf[512];

    topicString.cstring = topic;
    payloadlen = strlen(payload);
    len = MQTTSerialize_publish(buf,sizeof(buf),0,qos,0,packetid++,topicString,(unsigned char*)payload,payloadlen);
    Transport_SendPacket(buf,len);
}

/*********************************************************************
 * @fn      MQTT_Pingreq
 *
 * @brief   MQTT sends heartbeat packet
 *
 * @return  none
 */
void MQTT_Pingreq(void)
{
    uint32_t len;
    uint8_t buf[200];

    len = MQTTSerialize_pingreq(buf,sizeof(buf));
    Transport_SendPacket(buf,len);
}

/*********************************************************************
 * @fn      MQTT_Disconnect
 *
 * @brief   Disconnect the MQTT connection
 *
 * @return  none
 */
void MQTT_Disconnect(void)
{
    uint32_t len;
    uint8_t buf[50];
    len = MQTTSerialize_disconnect(buf,sizeof(buf));
    Transport_SendPacket(buf,len);
}

/*********************************************************************
 * @fn      msgDeal
 *
 * @brief   Dealing with subscription information.
 *
 * @param   msg - data buff
 *          len - data length
 *
 * @return  none
 */
void msgDeal(unsigned char *msg, int len)
{
    unsigned char *ptr = msg;
	uint8_t i;
	
    printf("payload len = %d\r\n",len);
    printf("payload: ");
    for( i = 0; i < len; i++)
    {
        printf("%c ",(uint16_t)*ptr);
        ptr++;
    }
    printf("\r\n");
}